﻿Shader "Lch/LitTerrain"
{
    Properties
    {
       
        [NoScaleOffset]_TextureArray0("图集0（_TextureArray0）", 2DArray) = "" {}
        [NoScaleOffset]_TextureArray1("图集1（_TextureArray1）", 2DArray) = "" {}
 
        [KeywordEnum(L4,L6, L8)] _Lay ("Use Tint", Float) = 0
        [NoScaleOffset]_Control0("控制图0(_Control0)", 2D) = "red" {}
        [NoScaleOffset]_Control1("控制图1(_Control1)", 2D) = "black" {}
      
        [Header(layer0)] 
        _Index0("第零层索引(_Index0)", Float) = 0
        [HDR]_Color0("颜色(_Color0)", Color) = (1, 1, 1, 0)
        _uv0("UV(_uv0)", Float) = 1
        _NormalScale0("法线缩放(_NormalScale0)", Range(0, 2)) = 1
        _Metallic0("金属度(_Metallic0)", Range(0, 1)) = 1
        _Smoothness0("光滑度(Smoothness0)", Range(0, 1)) = 1
        [Header(layer1)] 
        _Index1("第一层索引(_Index1)", Float) = 1
        [HDR]_Color1("颜色(_Color1)", Color) = (1, 1, 1, 0)
        _uv1("UV(_uv1)", Float) = 1
        _NormalScale1("法线缩放(_NormalScale1)", Range(0, 2)) = 1
        _Metallic1("金属度(_Metallic1)", Range(0, 1)) = 1
        _Smoothness1("光滑度(Smoothness1)", Range(0, 1)) = 1
        [Header(layer2)] 
        _Index2("第二层索引(_Index2)", Float) = 2
        [HDR]_Color2("颜色(_Color2)", Color) = (1, 1, 1, 0)
        _uv2("UV(_uv2)", Float) = 1
        _NormalScale2("法线缩放(_NormalScale2)", Range(0, 2)) = 1
        _Metallic2("金属度(_Metallic2)", Range(0, 1)) = 1
        _Smoothness2("光滑度(Smoothness2)", Range(0, 1)) = 1
        [Header(layer3)] 
        _Index3("第三层索引(_Index3）", Float) = 3
        [HDR]_Color3("颜色(_Color3)", Color) = (1, 1, 1, 0)
        _uv3("UV(_uv3)", Float) = 1
        _NormalScale3("法线缩放(_NormalScale3)", Range(0, 2)) = 1
        _Metallic3("金属度(_Metallic3)", Range(0, 1)) = 1
        _Smoothness3("光滑度(Smoothness3)", Range(0, 1)) = 1
        [Header(layer4)] 
        _Index4("第四层索引(_Index4)[!_LAY_L4]", Float) = 4
        [HDR]_Color4("颜色(_Color4)", Color) = (1, 1, 1, 0)
        _uv4("UV(_uv4)[!_LAY_L4]", Float) = 1
        _NormalScale4("法线缩放(_NormalScale4)[!_LAY_L4]", Range(0, 2)) = 1
        _Metallic4("金属度(_Metallic4)[!_LAY_L4]", Range(0, 1)) = 1
        _Smoothness4("光滑度(Smoothness4)[!_LAY_L4]", Range(0, 1)) = 1
        
        [Header(layer5)] 
        _Index5("第五层索引(_Index5)[!_LAY_L4]", Float) = 5
        _uv5("UV(_uv5)[!_LAY_L4]", Float) = 5
        [HDR]_Color5("颜色(_Color5)", Color) = (1, 1, 1, 0)
        _NormalScale5("法线缩放(_NormalScale5)[!_LAY_L4]", Range(0, 2)) = 1
        _Metallic5("金属度(_Metallic5)[!_LAY_L4]", Range(0, 1)) = 1
        _Smoothness5("光滑度(Smoothness5)[!_LAY_L4]", Range(0, 1)) = 1
        [Header(layer6)] 
        _Index6("第六层索引(_Index6)[_LAY_L8]", Float) = 6
        [HDR]_Color6("颜色(_Color6)", Color) = (1, 1, 1, 0)
        _uv6("UV(_uv6)[_LAY_L8]", Float) = 1
        _NormalScale6("法线缩放(_NormalScale6)[_LAY_L8]", Range(0, 2)) = 1
        _Metallic6("金属度(_Metallic6)[_LAY_L8]", Range(0, 1)) = 1
        _Smoothness6("光滑度(Smoothness6)[_LAY_L8]", Range(0, 1)) = 1
        [Header(layer7)] 
        _Index7("第七层索引(_Index7)[_LAY_L8]", Float) = 7
        [HDR]_Color7("颜色(_Color7)", Color) = (1, 1, 1, 0)
        _uv7("UV(_uv7[_LAY_L8])", Float) = 1
        _NormalScale7("法线缩放(_NormalScale7)[_LAY_L8]", Range(0, 2)) = 1
        _Metallic7("金属度(_Metallic7)[_LAY_L8]", Range(0, 1)) = 1
        _Smoothness7("光滑度(Smoothness7)[_LAY_L8]", Range(0, 1)) = 1

        _SpecularMaxLimit("光照最大限制",Range(1.0,50)) = 3.0
 
     

         

   

        [LCHEnum(LCHblendlModel)] _bendModel("混合模式", Int) = 0
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("源混合 SrcBlend", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("目标混合 DstBlend", Float) = 0
		[Enum(Off, 0, On, 1)]_ZWrite("深度写_ZWrite", float) = 1
		[Enum(UnityEngine.Rendering.CullMode)]_Cull("剔除模式", float) = 2
		_OffsetFactor("双材质防穿插,越小越前", Float) = 0
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }

        Pass
        {

            Name "ForwardLit"
            Tags{"LightMode" = "UniversalForward"}

            Blend[_SrcBlend][_DstBlend]
            ZWrite[_ZWrite]
            Cull[_Cull]
            //Offset -10, 1
            Offset [_OffsetFactor], [_OffsetFactor]
            HLSLPROGRAM
      
 
            //#pragma multi_compile_instancing

            //#pragma shader_feature_local_fragment _ALPHATEST_ON

            //#define CUSTOM_CUBEMAP_BRIGHTNESS
            #define _LIGHT_LAYERS
            #define   _SHADOWS_SOFT
            #define _MAIN_LIGHT_SHADOWS_CASCADE
            #define    _ADDITIONAL_LIGHTS
           
    
            #pragma multi_compile _LAY_L4 _LAY_L6 _LAY_L8
 
            #pragma multi_compile   _  LIGHTMAP_ON 

            #pragma multi_compile SHADOWS_SHADOWMASK

            //#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
           
             

           // #pragma multi_compile _ADDITIONAL_LIGHT_SHADOWS
            //Universal Render Pipeline/Lit, SubShader #0
            //SHADOWS_SHADOWMASK _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHT_SHADOWS _LIGHT_LAYERS _MAIN_LIGHT_SHADOWS_CASCADE _SHADOWS_SOFT
            
 

            //#pragma multi_compile   _ _SSS
            //#pragma multi_compile    ANISOTROPIC_NONE ANISOTROPIC_ON ANISOTROPIC_FLOWMAP


            // #pragma multi_compile    FOG_LINEAR FOG_EXP FOG_EXP2

           #pragma multi_compile   _ FOG_LINEAR    FOG_EXP FOG_EXP2
 
            //_ADDITIONAL_LIGHT_SHADOWS _LIGHT_LAYERS _MAIN_LIGHT_SHADOWS_CASCADE _SHADOWS_SOFT
            #define _NORMALMAP  

            #define MAIN_LIGHT_CALCULATE_SHADOWS
            #ifdef _NORMALMAP
            #define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 

            #endif

            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
          

            #define CUSTOM_VERTEX_PARAM 
            
            #include "lch_global_buffer.hlsl"
            #include "LitTerrainInput.hlsl"
            #include "lch_urp_com.hlsl"
            #include "lch_weather.hlsl"
            #pragma vertex vert
            #pragma fragment frag
          
            
            Varyings vert(Attributes input)
            {
                Varyings output = (Varyings)0;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_TRANSFER_INSTANCE_ID(input, output);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
                FillVaryingsData(input, output);
                output.uv = output.uv;
                return output;
            }
           
            half3 CalculateBlinnPhong(Light light, InputData inputData)
            {
                half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
                half3 lightColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
 
                #if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
                    half smoothness = exp2(10 * _SpecularColor.a + 1);
                    lightColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(_SpecularColor.rgb, 1), smoothness);
                #endif

                return lightColor;
            }
             #ifdef _SSS
            half3 LightingSSS(half3 lightColor ,half3 lightDirectionWS,half3 normalWS,half3 sssColor )
            {
 
                half NdotL =  dot(normalWS, lightDirectionWS) ;
    
                float3 sss  = 0.2*exp(-3.*abs(NdotL)/(sssColor+0.001));
   
                return sssColor *   sss;

            }
            half3 LightingSSS(Light light,half3 normalWS,LchSurfaceData surfaceData)
            {
 
                return LightingSSS(light.color.rgb,light.direction,normalWS ,surfaceData.sssColor.rgb );
 
            }
            #endif
            half4 frag(Varyings input,bool isFrontFace : SV_IsFrontFace) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
                 
                float2 uv = input.uv;

                LchSurfaceData surfaceData;
                InitializeLchSurfaceData(input.uv,input.color, surfaceData);
               
 
                
                InputData inputData;
                InitializeInputData(input,  isFrontFace, surfaceData.normalTS, inputData);
                Weather(surfaceData, inputData, input.normalWS,input.positionWS);

                 BRDFData brdfData;
                InitializeBRDFData(surfaceData , brdfData);

                LchAnisoData anisoData;
                InitAnisoData(surfaceData,anisoData,inputData);
                half4 shadowMask = CalculateShadowMask(inputData);
                shadowMask = 0.2+shadowMask*0.8;
                AmbientOcclusionFactor aoFactor;
                aoFactor.directAmbientOcclusion = 1.0;
                aoFactor.indirectAmbientOcclusion = surfaceData.occlusion;
 
                Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
                half3 ambient = inputData.bakedGI.rgb;
 
                MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);

                

                float NDotV;
                half3 giColor = LchGlobalIllumination(brdfData, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.normalWS, inputData.viewDirectionWS,NDotV);
           
                 
                #ifdef _SSS
                giColor *= surfaceData.sssAmb;
                #endif
                uint meshRenderingLayers = GetMeshRenderingLayer();
                half3 color = giColor; 
      
               
               
 
                if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
                {

                    
                    if(mainLight.direction.y>0.9999 && LchMainLightParams.w>0.5)
                    {   
                        mainLight.direction = normalize (LchMainLightParams.xyz-inputData.positionWS);
                    }
       
                    if(surfaceData.backLight>0)
                    {
                        color += LchLightingPhysicallyBasedBackLight(brdfData,anisoData, mainLight.color, mainLight.direction,   mainLight.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS,surfaceData.backLight ) ;  
                    }
                    else
                    {
                        color += LchLightingPhysicallyBased(brdfData,anisoData, mainLight.color, mainLight.direction,   mainLight.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS );  
                    }
                  
                    #ifdef _SSS
                    color.rgb += LightingSSS(mainLight,inputData.normalWS,surfaceData);
                    #endif
                      
                }
 
               #if defined(_ADDITIONAL_LIGHTS)
           
              uint pixelLightCount = GetAdditionalLightsCount();

 
              
                #if USE_CLUSTERED_LIGHTING
                for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
                {
                    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
                    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
                    {
                    
                        color += LchLightingPhysicallyBased(brdfData,anisoData, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS);  
                        
                    }
                    
                }
                #endif
               
                LIGHT_LOOP_BEGIN(pixelLightCount)
                    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
                    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
                    {
                        color += LchLightingPhysicallyBased(brdfData,anisoData, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, inputData.normalWS, inputData.viewDirectionWS);    
                    
                    }
                LIGHT_LOOP_END
                #endif
                #if defined(_ADDITIONAL_LIGHTS_VERTEX)
                lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
                #endif

                color.rgb = min(color.rgb,surfaceData.maxLimit);

                
                color.rgb += surfaceData.emission;

                color.rgb = MixFog(color.rgb, inputData.fogCoord);
               return float4(color,surfaceData.alpha);
            }
            ENDHLSL
        }

        
        Pass
		{
			
			Name "ShadowCaster"
			Tags { "LightMode"="ShadowCaster" }
			ZWrite On
			ZTest LEqual
			AlphaToMask Off
			ColorMask 0
			HLSLPROGRAM
			#define _NORMAL_DROPOFF_TS 1
			//#pragma multi_compile_instancing
 
	 
			#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
            //#pragma multi_compile _ DOTS_INSTANCING_ON

			#pragma vertex vert
			#pragma fragment ShadowPassFragmentFun

			#define SHADERPASS SHADERPASS_SHADOWCASTER

			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
			#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl"
            #define CBUFFER_ONLY
            #include "LitTerrainInput.hlsl"

			struct VertexInput
			{
				float4 positionOS : POSITION;

                float2 uv                       : TEXCOORD0;
				float3 normalOS : NORMAL;
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct VertexOutput
			{
				  float4 positionCS : SV_POSITION;
                  float2 uv                       : TEXCOORD0;
			 		
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};

 
			float3 _LightDirection;
			float3 _LightPosition;

			VertexOutput VertexFunction( VertexInput v )
			{
				VertexOutput o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );

				float3 positionWS = TransformObjectToWorld( v.positionOS.xyz );
				float3 normalWS = TransformObjectToWorldDir(v.normalOS);
				#if _CASTING_PUNCTUAL_LIGHT_SHADOW
					float3 lightDirectionWS = normalize(_LightPosition - positionWS);
				#else
					float3 lightDirectionWS = _LightDirection;
				#endif

				float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
				#if UNITY_REVERSED_Z
					positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE);
				#else
					positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE);
				#endif
				o.positionCS = positionCS;
                o.uv = v.uv;
				return o;
			}

			 
			VertexOutput vert ( VertexInput v )
			{
				return VertexFunction( v );
			}
 

            half4 ShadowPassFragmentFun(VertexOutput input) : SV_TARGET
            {
                 
                return 0;
            }
			 
			ENDHLSL
		} 

          

        Pass
        {
            Name "Meta"
            Tags{"LightMode" = "Meta"}

            Cull Off

            HLSLPROGRAM
      

            #pragma vertex UniversalVertexMeta
            #pragma fragment UniversalFragmentMetaLitFun

            #pragma shader_feature EDITOR_VISUALIZATION
            //#pragma shader_feature_local_fragment _SPECULAR_SETUP
            //#pragma shader_feature_local_fragment _EMISSION
 
            //#pragma shader_feature_local_fragment _ALPHATEST_ON
 
            
            #include "LitTerrainInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
    
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UniversalMetaPass.hlsl"
            half4 UniversalFragmentMetaLitFun(Varyings input) : SV_Target
            {

                LchSurfaceData surfaceData;
                InitializeLchSurfaceData(input.uv,1, surfaceData);
                MetaInput metaInput;
                metaInput.Albedo = surfaceData.albedo.xyz;
                metaInput.Emission = surfaceData.emission;
 
                return UniversalFragmentMeta(input, metaInput);
            }

            ENDHLSL
        }


        Pass
        {
            Name "DepthOnly"
            Tags{"LightMode" = "DepthOnly"}

            ZWrite On
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
   

            #pragma vertex DepthOnlyVertex
            #pragma fragment DepthOnlyFragment

            // -------------------------------------
            // Material Keywords
            //#pragma shader_feature_local_fragment _ALPHATEST_ON
           // #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            //#pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON

            
          
            #include "LitTerrainInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
            ENDHLSL
        }

        // This pass is used when drawing to a _CameraNormalsTexture texture
        /*Pass
        {
            Name "DepthNormals"
            Tags{"LightMode" = "DepthNormals"}

            ZWrite On
            Cull[_Cull]

            HLSLPROGRAM
            #pragma exclude_renderers gles gles3 glcore
            #pragma target 4.5

            #pragma vertex DepthNormalsVertex
            #pragma fragment DepthNormalsFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _NORMALMAP
 
            #pragma shader_feature_local_fragment _ALPHATEST_ON
 

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON

 
 
            #include "LitTerrainInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"
            ENDHLSL
        }*/
    }
    FallBack "Hidden/Shader Graph/FallbackError"

    CustomEditor "LCHShaderGUIBase" 
}